/**
 * 
 */
package com.ffcs.crmd.tsp.task.netty.processor;

import java.lang.Thread.State;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;

import com.ffcs.crmd.tsp.api.dto.job.TspJobDetailShell;
import com.ffcs.crmd.tsp.api.dto.netty.RemotingCommand;
import com.ffcs.crmd.tsp.api.dto.task.TspJobInstance;
import com.ffcs.crmd.tsp.api.netty.INettyProcessor;
import com.ffcs.crmd.tsp.api.netty.INettyRemotingClient;
import com.ffcs.crmd.tsp.api.task.job.IJob;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.common.netty.ResponseCode;
import com.ffcs.crmd.tsp.core.util.XmlUtil;
import com.ffcs.crmd.tsp.task.container.ThreadPoolContainer;
import com.ffcs.crmd.tsp.task.job.BusinessProcessor;
import com.ffcs.crmd.tsp.task.log.TaskLogger;
import com.ffcs.crmd.tsp.task.threadpool.JobProcessBusinessThreadPool;
import com.ffcs.crmd.tsp.task.threadpool.JobProcessThreadPool;
import com.ffcs.crmd.tsp.task.threadpool.JobRunnablePair;
import com.ffcs.crmd.tsp.task.threadpool.api.IJobProcessRunnable;

import io.netty.channel.ChannelHandlerContext;

/**
 * 功能说明:关闭子任务处理者
 *
 * @author ZHONGFUHUA
 * 
 * @since 2.0.0-SNAPSHOT
 *
 */
public class InterrruptJobDetailFinishProcessor implements INettyProcessor {

    /**
     * 日志
     */
    private static final Logger          LOG                          = TaskLogger.getLogger(LoggerName.TaskLoggerName);
    
    /**
     * 任务处理线程池
     */
    private JobProcessThreadPool         jobProcessThreadPool         = ThreadPoolContainer.getInstance().getJobProcessThreadPool();
    
    /**
     * 任务批量业务处理线程池
     */
    private JobProcessBusinessThreadPool jobProcessBusinessThreadPool = ThreadPoolContainer.getInstance().getJobProcessBusinessThreadPool();
    
    /**
     * 功能说明:
     * 
     * @param nettyRemotingClient
     */
    public InterrruptJobDetailFinishProcessor(INettyRemotingClient nettyRemotingClient) {
        
    }
    
    @Override
    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
        TspJobDetailShell tspJobDetailShell = XmlUtil.fromXml(new String(request.getBody()), TspJobDetailShell.class);
        TspJobInstance tspJobDetail = tspJobDetailShell.getContext().getTspJobInstance();
        LOG.debug("TASK-NETTY: recive a request to shutdown job detail[{}] opqque=[{}] id=[{}].",
            tspJobDetail.getJobKey(), request.getOpaque(), tspJobDetailShell.getId());
        
        String jobDetailShellId = tspJobDetailShell.getId();
        JobRunnablePair jobRunnablePair = jobProcessThreadPool.getThread(jobDetailShellId);
        Thread jobProcessThread = jobRunnablePair.getThread();
        IJobProcessRunnable jobProcessRunnable = jobRunnablePair.getRunnable();
        boolean shutdownOk = false;
        
        try {
            Class<?> jobClass = Class.forName(tspJobDetail.getJobClass());
            Object instance = jobClass.newInstance();
            if(instance instanceof IJob){
                shutdownOk = shutdownJobProcessThread(jobProcessThread, jobDetailShellId);
            }else{
                if(jobProcessRunnable.getReturnWaitting().getCount() == 1){
                    Map<BusinessProcessor<Object>, Object> businessProcessThradMap = jobProcessRunnable.getBusinessProcessThreadMap();
                    List<Object> businessDataList = new ArrayList<Object>();
                    businessDataList.addAll(businessProcessThradMap.values());
                    
                    for(Object object : businessDataList){
                        Thread jobProcessBusinessThread = jobProcessBusinessThreadPool.getThread(object);
                        jobProcessBusinessThread.interrupt();
                    }
                    
                    Thread.sleep(2000);
                    
                    if(businessProcessThradMap.isEmpty()){
                        shutdownOk = true;
                    }
                }else{
                    shutdownOk = shutdownJobProcessThread(jobProcessThread, jobDetailShellId);
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InterruptedException e) {
            LOG.error("TASK-NETTY: shutdown job detail process thread exception:", e);
        }
        
        LOG.debug("TASK-NETTY: shutdown {} a job detail[{}] opaque=[{}] id=[{}] ok.",
            shutdownOk ? "success": "fail", tspJobDetail.getJobKey(), request.getOpaque(), jobDetailShellId);
        
        RemotingCommand response = RemotingCommand.createResponseCommand(ResponseCode.SUCCESS);
        response.setBody((String.valueOf(shutdownOk)).getBytes());
        return response;
    }
    
    /**
     * 
     * 功能说明:关闭任务处理线程
     * 
     * @param thread 线程
     * @return 关闭是否成功
     * @throws InterruptedException 
     */
    public boolean shutdownJobProcessThread(Thread thread, String id) throws InterruptedException{
        if(thread.getState() == State.TIMED_WAITING || thread.getState() == State.WAITING){
            thread.interrupt();
        }
        
        Thread.sleep(2000);
        
        JobRunnablePair jobRunnablePair = jobProcessThreadPool.getThread(id);
        if(jobRunnablePair == null){
            return true;
        }
        return false;
    }
    
    
}
